/*-----------------------------------------------File Info------------------------------------------------
** File Name:               pwm user.c  
** Last modified date:      2022.07.22
** Last version:            V0.1
** Description:             
**--------------------------------------------------------------------------------------------------------            
** Created date:            2016.09.07
** author:                  YLY
** Version:                 V0.1
** Descriptions:            pwm
**--------------------------------------------------------------------------------------------------------
*/
#include "bspPWM.h"

/**
    \brief      configure the TIMER peripheral
    \param[in]  *pwm	DEV_PWMx
    \param[in]  freq	频率
    \param[in]  duty	占空比0.000~1.000
    \retval     none
  */
int8_t pwmInit(tsPwm *pwm, uint32_t freq, float duty)	//freq,
{
	timer_parameter_struct 		timer_initpara;		//定时器基本参数
	timer_oc_parameter_struct 	timer_ocintpara;	//定时器输出参数
	
	double needPeriod,maxPeriod,minPeriod;
    uint16_t prescaler;                        		//预分频值
    uint16_t period;                          		//装载值
	uint32_t pulse;							   		//占空比

	if(pwm == NULL)
		return -1;
	
	/* 初始化GPIO */
	gpioConfig(&pwm->gpio);
	
	/* 计算频率 */
	needPeriod =  1000000000.0/(double)freq;					//频率转为周期,单位nS
	maxPeriod = 65536.0*(1000000000.0/(double)SystemCoreClock);	//最大可计数周期
	
	prescaler = (uint16_t)(needPeriod/maxPeriod);				//计算预分频,所需周期*最大可计数周期
	minPeriod = 1000000000.0/((double)SystemCoreClock/(double)(prescaler+1));	//分频单次周期时间
	period = needPeriod/minPeriod;
	pulse = (uint32_t)(duty*period);

	/* 初始化定时器 */	
    rcu_periph_clock_enable(pwm->timerRcu);
    timer_deinit(pwm->timerPeriph);

    /* pwm->timer_periph configuration */
    timer_initpara.prescaler         = prescaler;					//预分频值
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;			//对齐模式-边沿模式
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;			//计数方向
    timer_initpara.period            = period;						//装载值
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;			//时钟分频
    timer_initpara.repetitioncounter = 0;							//计数重复值
    timer_init(pwm->timerPeriph, &timer_initpara);
	
	
	//配置PWM
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;			//通道输出状态
    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;			//通道互补输出状态
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;		//通道输出极性
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;		//通道互补输出极性
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;		//通道输出的空闲状态
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;	//信道互补输出的空闲状态
    timer_channel_output_config(pwm->timerPeriph, pwm->channel, &timer_ocintpara);

    timer_channel_output_pulse_value_config(pwm->timerPeriph, pwm->channel, pulse);	//第三个参数是占空比,需要与频率对应100
    timer_channel_output_mode_config(pwm->timerPeriph, pwm->channel, TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(pwm->timerPeriph, pwm->channel, TIMER_OC_SHADOW_DISABLE);

    timer_primary_output_config(pwm->timerPeriph, ENABLE);
    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(pwm->timerPeriph);
	
	timer_enable(pwm->timerPeriph);
	return 0;
}

int8_t pwmSet(tsPwm *pwm, uint32_t freq, float duty)
{
	return pwmInit(pwm, freq, duty);
}

int8_t pwmEnable(tsPwm *pwm)
{
	if(pwm == NULL)
		return -1;
	
    timer_channel_output_mode_config(pwm->timerPeriph, pwm->channel, TIMER_OC_MODE_PWM0);	
	/* enable TIMER primary output function */
    timer_primary_output_config(pwm->timerPeriph, ENABLE);
	
	timer_enable(pwm->timerPeriph);
	return 0;
}

int8_t pwmDisable(tsPwm *pwm)
{
	if(pwm == NULL)
		return -1;
	
	timer_disable(pwm->timerPeriph);
	
	/* enable TIMER primary output function */
    timer_primary_output_config(pwm->timerPeriph, DISABLE);
	timer_channel_output_mode_config(pwm->timerPeriph,pwm->channel,TIMER_OC_MODE_LOW);
	return 0;
}



